WITH Ada.Text_IO;
WITH Ada.Strings.Unbounded;
WITH Petrinets;
WITH Application;

PACKAGE BODY Test_Cases_Petrinet IS


   -- Initialisation de la suite de test
   PROCEDURE Set_Up IS
   BEGIN
      Unit_Test_Assertions.Init;

      testRDP := Rdp.Xml_Build (Ada.Strings.Unbounded.To_String(Application.Xml_Path) & "RdP-Test_petrinet.xml","petrinet");
      resultBool := False;
      resultInt := 0;

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line("--------------------------------------------------------------------------------");
      Ada.Text_IO.Put_Line("## Suite de test de validite des fonctions du reseau de Petri ##");
      Rdp.Put (testRDP);

   END Set_Up;


   -- Terminaison de la suite de test
   PROCEDURE Tear_Down (nbTest : OUT Integer; nbError : OUT Integer; name : OUT Dyn_Str.Unbounded_String) IS
   BEGIN

      nbTest := Unit_Test_Assertions.Get_Tests_Count;
      nbError := Unit_Test_Assertions.Get_Error_Count;
      name := Dyn_Str.To_Unbounded_String("test_cases_petrinet");
      Ada.Text_IO.Put_Line("--------------------------------------------------------------------------------");
      Ada.Text_IO.New_Line;

   END Tear_Down;


   -- Demarrage de la suite de tests
   PROCEDURE Run IS
   BEGIN

      Test_Get_Nb_Place ;
      Test_Get_Nb_Transition ;
      Test_Is_Place ;
      Test_Is_Transition ;
      Test_Get_Place_Index ;
      Test_Get_Transition_Index ;
      Test_Get_Init_Mark ;
      Test_Has_Post_Arrow ;
      Test_Has_Pre_Arrow ;
      Test_Get_Post_Arrow_Weight ;
      Test_Get_Pre_Arrow_Weight ;

   END Run;


   -- Test de la recuparation du nombre de places
   PROCEDURE Test_Get_Nb_Place IS
   BEGIN

      Ada.Text_IO.New_Line;
      resultInt := Rdp.Get_Nb_Place (testRDP);
      Unit_Test_Assertions.Assert_Integer (resultInt, 2, "Recuperation du nombre de places (Get_Nb_Place) ");

   END Test_Get_Nb_Place;


   -- Test de la recuparation du nombre de transitions
   PROCEDURE Test_Get_Nb_Transition IS
   BEGIN

      Ada.Text_IO.New_Line;
      resultInt := Rdp.Get_Nb_Transition (testRDP);
      Unit_Test_Assertions.Assert_Integer (resultInt, 3, "Recuperation du nombre de transitions (Get_Nb_Transition)");

   END Test_Get_Nb_Transition;


   -- Test de l'existence des places
   PROCEDURE Test_Is_Place IS
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Test d'existences des places (Is_Place)");

      resultBool := Rdp.Is_Place (testRDP, Dyn_Str.To_Unbounded_String("P1"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  Place existente #P1 ");

      resultBool := Rdp.Is_Place (testRDP, Dyn_Str.To_Unbounded_String("P2"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  Place existente #P2 ");

      resultBool := Rdp.Is_Place (testRDP, Dyn_Str.To_Unbounded_String("P3"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, False,  "  Place non existente #P3 ");

      resultBool := Rdp.Is_Place (testRDP, Dyn_Str.To_Unbounded_String("T1"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, False,  "  Transition #T1 ");

   END Test_Is_Place;


   -- Test de l'existence des transitions
   PROCEDURE Test_Is_Transition IS
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Test d'existences des transition (Is_Transition)");

      resultBool := Rdp.Is_Transition (testRDP, Dyn_Str.To_Unbounded_String("T1"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  Transition existente #T1 ");

      resultBool := Rdp.Is_Transition (testRDP, Dyn_Str.To_Unbounded_String("T2")) ;
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  Transition existente #T2 ");

      resultBool := Rdp.Is_Transition (testRDP, Dyn_Str.To_Unbounded_String("T3")) ;
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  Transition existente #T3 ");

      resultBool := Rdp.Is_Transition (testRDP, Dyn_Str.To_Unbounded_String("T5"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, False,  "  Transition non existente #T5 ");

      resultBool := Rdp.Is_Transition (testRDP, Dyn_Str.To_Unbounded_String("P1"));
      Unit_Test_Assertions.Assert_Boolean (resultBool, False,  "  Place #P1 ");

   END Test_Is_Transition;


   -- Test de la recuperation de l'index d'une place via son nom
   PROCEDURE Test_Get_Place_Index IS
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Recuperation de l'index d'une place (Get_Place_Index)");

      ResultInt := Rdp.Get_Place_Index (TestRDP, Dyn_Str.To_Unbounded_String ("P1"));
      Unit_Test_Assertions.Assert_Integer (resultInt, 1, "  Place existente #P1 ");

      resultInt := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P2"));
      Unit_Test_Assertions.Assert_Integer (resultInt, 2, "  Place existente #P2 ");

      begin
         resultBool := False;
         resultInt := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P5"));
      exception
         when Rdp.Place_Not_Found =>
            resultBool := True;
         when others =>
            resultBool := False;
      end;
      Unit_Test_Assertions.Assert_Boolean (resultBool, True, "  Place non existente #P2 (Raise: Place_Not_Found)");

   END Test_Get_Place_Index;


   -- Test de la recuperation de l'index d'une transition via son nom
   PROCEDURE Test_Get_Transition_Index IS
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Recuperation de l'index d'une Transition (Get_Transition_Index)");

      resultInt := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T1"));
      Unit_Test_Assertions.Assert_Integer (resultInt, 1, "  Transition existente #T1 ");

      resultInt := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T2"));
      Unit_Test_Assertions.Assert_Integer (resultInt, 2, "  Transition existente #T2 ");

      begin
         resultBool := False;
         resultInt := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T5"));
      exception
         when Rdp.Transition_Not_Found =>
            resultBool := True;
         when others =>
            resultBool := False;

      end;
      Unit_Test_Assertions.Assert_Boolean (resultBool, True, "  Transition non existente #T5 (Raise: Transition_Not_Found)");

   END Test_Get_Transition_Index;


   -- Test de la recuperation du marquage initial d'une place par son index
   PROCEDURE Test_Get_Init_Mark IS
      indexP 		: Integer;
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Recuperation du marquage initial d'une place (Get_Init_Mark)");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P1"));
      resultInt :=  Rdp.Get_Init_Mark (testRDP, indexP);
      Unit_Test_Assertions.Assert_Integer (resultInt, 1, "  Place existente #P1 ");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P2"));
      resultInt := Rdp.Get_Init_Mark (testRDP, indexP);
      Unit_Test_Assertions.Assert_Integer (resultInt, 0, "  Place existente #P2 ");

      begin
         resultBool := False;
         indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P3"));
         resultInt := Rdp.Get_Init_Mark (testRDP, indexP) ;
      exception
         when Rdp.Place_Not_Found =>
            resultBool := True;
         when others =>
            resultBool := False;
      end;
      Unit_Test_Assertions.Assert_Boolean (resultBool, True, "  Place non existente #P3 (Raise: Place_Not_Found)");

   END Test_Get_Init_Mark;


   -- Test de l'existence d'un arc rentrant
   PROCEDURE Test_Has_Post_Arrow IS
      indexP, indexT		: Integer;
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Test d'existence d'un arc rentrant (Has_Post_Arrow)");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P1"));
      indexT := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T2"));
      resultBool := Rdp.Has_Post_Arrow (testRDP, indexP, indexT);
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  #T2 ----> #P1 ");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P1"));
      indexT := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T1"));
      resultBool := Rdp.Has_Post_Arrow (testRDP, indexP, indexT);
      Unit_Test_Assertions.Assert_Boolean (resultBool, False,  "  #T1 -//-> #P1 ");

   END Test_Has_Post_Arrow;


   -- Test de l'existence d'un arc sortant
   PROCEDURE Test_Has_Pre_Arrow IS
      indexP, indexT		: Integer;
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line (" Test d'existence d'un arc sortant (Has_Pre_Arrow)");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P2"));
      indexT := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T2"));
      resultBool := Rdp.Has_Pre_Arrow (testRDP, indexP, indexT);
      Unit_Test_Assertions.Assert_Boolean (resultBool, True,  "  #P2 ----> #T2 ");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P2"));
      indexT := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T1"));
      resultBool := Rdp.Has_Pre_Arrow (testRDP, indexP, indexT);
      Unit_Test_Assertions.Assert_Boolean (resultBool, False,  "  #P2 -//-> #T1 ");

   END Test_Has_Pre_Arrow;


   -- Test du poids d'un arc rentrant
   PROCEDURE Test_Get_Post_Arrow_Weight IS
      indexP, indexT		: Integer;
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Recuperation du poids d'un arc sortant (Get_Post_Arrow_Weight)");
      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P1"));
      indexT := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T2"));
      resultInt := Rdp.Get_Post_Arrow_Weight (testRDP, indexP, indexT);
      Unit_Test_Assertions.Assert_Integer (resultInt, 1, "  Arc #T2 ----> #P1 ");

   END Test_Get_Post_Arrow_Weight;


   -- Test du poids d'un arc sortant
   PROCEDURE Test_Get_Pre_Arrow_Weight IS
      indexP, indexT		: Integer;
   BEGIN

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(" Recuperation du poids d'un arc rentrant (Get_Pre_Arrow_Weight)");

      indexP := Rdp.Get_Place_Index (testRDP, Dyn_Str.To_Unbounded_String("P2"));
      indexT := Rdp.Get_Transition_Index (testRDP, Dyn_Str.To_Unbounded_String("T2"));
      resultInt :=  Rdp.Get_Pre_Arrow_Weight (testRDP, indexP, indexT);
      Unit_Test_Assertions.Assert_Integer (resultInt, 1, "  Arc #P2 ----> #T2 ");

   END Test_Get_Pre_Arrow_Weight;


END Test_Cases_Petrinet;
